﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace K3DesktopClient
{
    public class KingdeeSignature
    {
        public static string GetSignature(string[] arr)
        {
            Array.Sort(arr, StringComparer.Ordinal);
            string arrString = string.Join("", arr);
            SHA1 sha = SHA1.Create();
            byte[] sha1Arr = sha.ComputeHash(Encoding.UTF8.GetBytes(arrString));
            StringBuilder enText = new();
            foreach (byte b in sha1Arr)
            {
                _ = enText.AppendFormat("{0:x2}", b);
            }
            return enText.ToString();
        }

        public static string Encode(object data)
        {
            string KEY_64 = "KingdeeK";
            string IV_64 = "KingdeeK";
            string result;
            try
            {
                byte[] byKey = Encoding.ASCII.GetBytes(KEY_64);
                byte[] byIV = Encoding.ASCII.GetBytes(IV_64);
                byte[] buffer = null;
                int msleng = 0;
                using (DES cryptoProvider = DES.Create())
                {
                    int keySize = cryptoProvider.KeySize;
                    using MemoryStream ms = new();
                    using CryptoStream cst = new(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);
                    using StreamWriter sw = new(cst);
                    sw.Write(data);
                    sw.Flush();
                    cst.FlushFinalBlock();
                    sw.Flush();
                    buffer = ms.GetBuffer();
                    msleng = (int)ms.Length;
                }
                result = Convert.ToBase64String(buffer, 0, msleng);
            }
            catch (Exception x)
            {
                result = x.Message;
            }
            return result;
        }

        /// <summary>
        /// HMACSHA256加密
        /// </summary>
        /// <param name="message"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static string HmacSHA256(string message, string secret, Encoding encoding, bool isHex = false)
        {
            secret ??= "";
            byte[] keyByte = encoding.GetBytes(secret);
            byte[] messageBytes = encoding.GetBytes(message);
            string result;
            using (HMACSHA256 hmacsha256 = new(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                if (isHex)
                {
                    string hexstr = ByteToHexStr(hashmessage).ToLower();
                    result = Convert.ToBase64String(encoding.GetBytes(hexstr));
                }
                else
                {
                    result = Convert.ToBase64String(hashmessage);
                }
            }
            return result;
        }

        public static string ByteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }

        /// <summary>
        /// 加密AppSecret（第三方系统登录授权）
        /// </summary>
        /// <param name="appSecret"></param>
        /// <returns></returns>
        internal static string EncryptAppSecret(string appSecret)
        {
            if (Regex.IsMatch(appSecret, "^([0-9a-zA-Z]{32})$"))
            {
                byte[] buff = Convert.FromBase64String(appSecret);
                return Convert.ToBase64String(XOREncode(buff));
            }
            return ROT13Encode(appSecret);
        }

        /// <summary>
        /// 解密AppSecret（第三方系统登录授权）
        /// </summary>
        /// <param name="appSecret"></param>
        /// <returns></returns>
        public static string DecryptAppSecret(string appSecret)
        {
            if (appSecret.Length == 32)
            {
                byte[] buff2 = Convert.FromBase64String(appSecret);
                return Convert.ToBase64String(XOREncode(buff2));
            }
            return ROT13Encode(appSecret);
        }

        /// <summary>
        /// 异或编码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private static byte[] XOREncode(byte[] input)
        {
            string s = "0054f397c6234378b09ca7d3e5debce7";
            byte[] array = new byte[input.Length];
            byte[] bytes = Encoding.UTF8.GetBytes(s);
            for (int i = 0; i < input.Length; i++)
            {
                array[i] = BitConverter.GetBytes(input[i] ^ bytes[i])[0];
            }
            return array;
        }

        /// <summary>
        /// ROT13编码
        /// </summary>
        /// <param name="InputText"></param>
        /// <returns></returns>
        private static string ROT13Encode(string InputText)
        {
            string EncodedText = "";
            for (int i = 0; i < InputText.Length; i++)
            {
                char CurrentCharacter = Convert.ToChar(InputText.Substring(i, 1));
                int CurrentCharacterCode = CurrentCharacter;
                if (CurrentCharacterCode is >= 97 and <= 109)
                {
                    CurrentCharacterCode += 13;
                }
                else if (CurrentCharacterCode is >= 110 and <= 122)
                {
                    CurrentCharacterCode -= 13;
                }
                else if (CurrentCharacterCode is >= 65 and <= 77)
                {
                    CurrentCharacterCode += 13;
                }
                else if (CurrentCharacterCode is >= 78 and <= 90)
                {
                    CurrentCharacterCode -= 13;
                }
                EncodedText += (char)CurrentCharacterCode;
            }
            return EncodedText;
        }

        public static string UrlEncodeWithUpperCode(string str, Encoding encoding)
        {
            StringBuilder builder = new();
            foreach (char c in str)
            {
                _ = HttpUtility.UrlEncode(c.ToString()).Length > 1
                    ? builder.Append(HttpUtility.UrlEncode(c.ToString(), encoding).ToUpper())
                    : builder.Append(c);
            }
            return builder.ToString();
        }
    }
    public class DateTimeFormatUtils
    {
        private static readonly DateTime Jan1st1970 = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        /// <summary>
        /// 时间戳(毫秒)
        /// </summary>
        /// <returns></returns>
        public static long CurrentTimeMillis()
        {
            return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
        }

        /// <summary>
        /// 时间戳(秒)
        /// </summary>
        public static long CurrentTimeSeconds()
        {
            return (long)(DateTime.UtcNow - Jan1st1970).TotalSeconds;
        }
    }

    public class CloudToBase64
    {
        private readonly byte[] xBuff = null;
        public CloudToBase64(string arg)
        {
            xBuff = Encoding.Default.GetBytes(arg);
        }
        public override string ToString()
        {
            return Convert.ToBase64String(xBuff);
        }
    }
}
